#include <gtest/gtest.h>
#include "event_storage.h"
#include "base_log.h"
#include <sqlite3.h>
#include <unistd.h>
#include <sys/stat.h>

using json = nlohmann::json;
using namespace El::Event;

class EventStorageTest : public ::testing::Test {
protected:
    void SetUp() override
    {
        // Use a temporary path for testing
        std::string temp_db = "/tmp/test_event.db";
        json config = {{"db_path", temp_db}, {"max_events", 1000}};
        
        // Clean up any existing test database
        struct stat st;
        if (stat(temp_db.c_str(), &st) == 0) {
            unlink(temp_db.c_str());
        }
        
        ASSERT_TRUE(storage->init(config));
    }

    void TearDown() override {
        storage->deinit();
    }

    IStorage *storage = &IStorage::GetInstance();
};

TEST_F(EventStorageTest, StoreAndQueryEvent)
{
    json event = {{"timestamp", 1637000000000},
                  {"event_type", "motion_detected"},
                  {"status", "new"},
                  {"data", {{"location", "entrance"}, {"confidence", 0.95}}}};

    EXPECT_EQ(storage->count(), 0);
    EXPECT_TRUE(storage->store(event));
    event["timestamp"] = 1637000001000;
    EXPECT_TRUE(storage->store(event));

    auto count = storage->count();
    EXPECT_EQ(count, 2);

    auto start_time = 1636999999000;
    auto end_time = 1637000002000;
    
    auto results = storage->query(start_time, end_time, "motion_detected");
    EXPECT_EQ(results.size(), 2);
}

TEST_F(EventStorageTest, QueryWithEmptyTimeRange)
{
    json event = {{"timestamp", 1637000000000},
                  {"event_type", "motion_detected"},
                  {"status", "new"},
                  {"data", {{"location", "entrance"}, {"confidence", 0.95}}}};
    
    EXPECT_TRUE(storage->store(event));
    
    // 测试空的时间范围
    auto results = storage->query(0, 0, "");
    EXPECT_EQ(results.size(), 1);
}

TEST_F(EventStorageTest, QueryWithInvalidTimeRange)
{
    json event = {{"timestamp", 1637000000000},
                  {"event_type", "motion_detected"},
                  {"status", "new"},
                  {"data", {{"location", "entrance"}, {"confidence", 0.95}}}};
    
    EXPECT_TRUE(storage->store(event));
    
    // 测试结束时间小于开始时间的情况
    auto results = storage->query(1637000001000, 1637000000000, "motion_detected");
    EXPECT_EQ(results.size(), 0);
}

TEST_F(EventStorageTest, QueryWithDifferentEventTypes)
{
    json event1 = {{"timestamp", 1637000000000},
                   {"event_type", "motion_detected"},
                   {"status", "new"},
                   {"data", {{"location", "entrance"}}}};
    
    json event2 = {{"timestamp", 1637000001000},
                   {"event_type", "face_detected"},
                   {"status", "new"},
                   {"data", {{"location", "entrance"}}}};
    
    EXPECT_TRUE(storage->store(event1));
    EXPECT_TRUE(storage->store(event2));
    
    auto results1 = storage->query(0, 1637000002000, "motion_detected");
    EXPECT_EQ(results1.size(), 1);
    
    auto results2 = storage->query(0, 1637000002000, "face_detected");
    EXPECT_EQ(results2.size(), 1);
    
    auto results3 = storage->query(0, 1637000002000, "");
    EXPECT_EQ(results3.size(), 2);
}

TEST_F(EventStorageTest, TestMaxEventsLimit)
{
    json event = {{"timestamp", 1637000000000},
                  {"event_type", "motion_detected"},
                  {"status", "new"},
                  {"data", {{"location", "entrance"}}}};
    
    for(int i = 0; i < 1001; i++) {
        event["timestamp"] = 1637000000000 + i;
        EXPECT_TRUE(storage->store(event));
    }
    
    EXPECT_EQ(storage->count(), 1000);
}

TEST_F(EventStorageTest, TestInvalidEventData)
{
    json invalid_event1 = {{"status", "new"},
                          {"data", {{"location", "entrance"}}}};
    
    EXPECT_FALSE(storage->store(invalid_event1));
    
    json invalid_event2 = {{"timestamp", "invalid_time"},
                          {"event_type", "motion_detected"},
                          {"status", "new"},
                          {"data", {{"location", "entrance"}}}};
    
    EXPECT_FALSE(storage->store(invalid_event2));
}

TEST_F(EventStorageTest, QueryEventTypeFilter)
{
    // 存储不同类型的事件
    json event1 = {{"timestamp", 1637000000000},
                   {"event_type", "motion_detected"},
                   {"status", "new"},
                   {"data", {{"location", "entrance"}}}};
    
    json event2 = {{"timestamp", 1637000001000},
                   {"event_type", "face_detected"},
                   {"status", "new"},
                   {"data", {{"location", "entrance"}}}};
    
    json event3 = {{"timestamp", 1637000002000},
                   {"event_type", "motion_detected"},
                   {"status", "new"},
                   {"data", {{"location", "backyard"}}}};

    EXPECT_TRUE(storage->store(event1));
    EXPECT_TRUE(storage->store(event2));
    EXPECT_TRUE(storage->store(event3));

    // 测试空字符串过滤器（应返回所有事件）
    auto all_results = storage->query(1637000000000, 1637000003000, "");
    EXPECT_EQ(all_results.size(), 3);

    // 测试特定事件类型过滤器
    auto motion_results = storage->query(1637000000000, 1637000003000, "motion_detected");
    EXPECT_EQ(motion_results.size(), 2);

    auto face_results = storage->query(1637000000000, 1637000003000, "face_detected");
    EXPECT_EQ(face_results.size(), 1);

    // 测试不存在的事件类型
    auto nonexistent_results = storage->query(1637000000000, 1637000003000, "nonexistent_type");
    EXPECT_EQ(nonexistent_results.size(), 0);
}

TEST_F(EventStorageTest, QueryEventTypeFilterWithTimeRange)
{
    // 存储多个时间点的不同类型事件
    json event1 = {{"timestamp", 1637000000000},
                   {"event_type", "motion_detected"},
                   {"status", "new"},
                   {"data", {{"location", "entrance"}}}};
    
    json event2 = {{"timestamp", 1637000010000},
                   {"event_type", "motion_detected"},
                   {"status", "new"},
                   {"data", {{"location", "entrance"}}}};
    
    json event3 = {{"timestamp", 1637000020000},
                   {"event_type", "face_detected"},
                   {"status", "new"},
                   {"data", {{"location", "entrance"}}}};

    EXPECT_TRUE(storage->store(event1));
    EXPECT_TRUE(storage->store(event2));
    EXPECT_TRUE(storage->store(event3));

    // 测试时间范围内的空字符串过滤器
    auto all_results = storage->query(1637000005000, 1637000015000, "");
    EXPECT_EQ(all_results.size(), 1);

    // 测试时间范围内的特定类型过滤器
    auto motion_results = storage->query(1637000005000, 1637000015000, "motion_detected");
    EXPECT_EQ(motion_results.size(), 1);

    // 测试时间范围内的不存在类型
    auto face_results = storage->query(1637000005000, 1637000015000, "face_detected");
    EXPECT_EQ(face_results.size(), 0);
}

TEST_F(EventStorageTest, TestHumanDetectEvent)
{
    json event = {
        {"timestamp", 1637000000000},
        {"event_type", "HUMAN_DETECT"},
        {"status", "new"},
        {"data", {
            {"confidence", 92},
            {"target", {
                {"type", "human"},
                {"rect", {
                    {"left", 0.2},
                    {"top", 0.1},
                    {"width", 0.15},
                    {"height", 0.4}
                }},
                {"attributes", {
                    {"posture", "standing"},
                    {"direction", 180},
                    {"speed", 1.2}
                }}
            }}
        }}
    };
    
    EXPECT_TRUE(storage->store(event));
    auto results = storage->query(1637000000000, 1637000001000, "HUMAN_DETECT");
    EXPECT_EQ(results.size(), 1);
}

TEST_F(EventStorageTest, TestMultipleEventTypes)
{
    // 测试多种不同类型的事件存储和查询
    std::vector<std::string> event_types = {
        "MOTION_DETECT",
        "HUMAN_DETECT",
        "FACE_DETECT",
        "LINE_CROSSING",
        "REGION_INTRUSION",
        "AUDIO_DETECT"
    };
    
    int64_t base_time = 1637000000000;
    
    // 存储每种类型的事件
    for (size_t i = 0; i < event_types.size(); i++) {
        json event = {
            {"timestamp", base_time + i * 1000},
            {"event_type", event_types[i]},
            {"status", "new"},
            {"data", {{"confidence", 90}}}
        };
        EXPECT_TRUE(storage->store(event));
    }
    
    // 验证总数
    EXPECT_EQ(storage->count(), event_types.size());
    
    // 验证每种类型的查询结果
    for (const auto& type : event_types) {
        auto results = storage->query(base_time, base_time + 1000000, type);
        EXPECT_EQ(results.size(), 1);
    }
}

TEST_F(EventStorageTest, TestEventStatus)
{
    // 测试事件的不同状态：start、update、end
    json event = {
        {"timestamp", 1637000000000},
        {"event_type", "REGION_INTRUSION"},
        {"status", "start"},
        {"data", {
            {"confidence", 90},
            {"region_id", "region_1"},
            {"duration", 0}
        }}
    };
    
    EXPECT_TRUE(storage->store(event));
    
    // 更新状态
    event["timestamp"] = 1637000001000;
    event["status"] = "update";
    event["data"]["duration"] = 1;
    EXPECT_TRUE(storage->store(event));
    
    // 结束状态
    event["timestamp"] = 1637000002000;
    event["status"] = "end";
    event["data"]["duration"] = 2;
    EXPECT_TRUE(storage->store(event));
    
    auto results = storage->query(1637000000000, 1637000003000, "REGION_INTRUSION");
    EXPECT_EQ(results.size(), 3);
}